﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using HalconDotNet;
using PylonCamera;
using Separate.Model.Vision;
using Commonality.Model;

namespace Separate.BLL
{
    public partial class VisionWindow : Form
    {
        public CPylonCamera Camera;
        public string CameraName;
        public HObject m_image;
        private HTuple hv_win;
        private double row, col, phi, lenth1, lenth2, threshold, minarea;  //视觉检测参数
        public VisionWindow(string cameraName)
        {
            InitializeComponent();
            CameraName = cameraName;

            Control.CheckForIllegalCrossThreadCalls = false;
            this.WindowState = FormWindowState.Maximized;
            hv_win = new HTuple();
            hv_win = this.hWindowControl.HalconWindow;
            HOperatorSet.SetPart(hv_win, 0, 0, 3036 - 1, 4024 - 1);

            HObject empty_image;             //开始运行时显示一张空照片，不然halcon会有bug
            HOperatorSet.GenEmptyObj(out empty_image);
            empty_image.Dispose();
            HOperatorSet.ReadImage(out empty_image, Application.StartupPath + "\\Tool\\Empty.bmp");
            HOperatorSet.DispObj(empty_image, hv_win);
            empty_image.Dispose();
        }

        private void VisionWindow_Load(object sender, EventArgs e)
        {
            Camera = new CPylonCamera();
            VisionPamraLoad(CameraName);
        }
        private void VisionPamraLoad(string name)
        {
            row = Convert.ToDouble(OperateIniFile.ReadIniData("Device", name + "row", "", Application.StartupPath + @"\Tool\Device.ini"));
            col = Convert.ToDouble(OperateIniFile.ReadIniData("Device", name + "col", "", Application.StartupPath + @"\Tool\Device.ini"));
            phi = Convert.ToDouble(OperateIniFile.ReadIniData("Device", name + "phi", "", Application.StartupPath + @"\Tool\Device.ini"));
            lenth1 = Convert.ToDouble(OperateIniFile.ReadIniData("Device", name + "lenth1", "", Application.StartupPath + @"\Tool\Device.ini"));
            lenth2 = Convert.ToDouble(OperateIniFile.ReadIniData("Device", name + "lenth2", "", Application.StartupPath + @"\Tool\Device.ini"));
            threshold = Convert.ToDouble(OperateIniFile.ReadIniData("Device", name + "threshold", "", Application.StartupPath + @"\Tool\Device.ini"));
            minarea = Convert.ToDouble(OperateIniFile.ReadIniData("Device", name + "minarea", "", Application.StartupPath + @"\Tool\Device.ini"));
            Log4Net.MsgInfo("加载" + CameraName + "视觉参数");
        }
        public bool OpenCamera()
        {

            return Camera.OpenCamera(CameraName);
        }
        public void CloseCamera()
        {
            Camera.CameraClose();
        }

        public void DispObj()
        {
            HOperatorSet.GenEmptyObj(out m_image);
            m_image.Dispose();
            Camera.GrabOnePic(out m_image);
            HOperatorSet.DispObj(m_image, hv_win);
            m_image.Dispose();
        }


        public HObject m_imageAuto;
        public string Detection()     //异物检测
        {
            string detection_result = "";
            Tuple<bool, bool> str = new Tuple<bool, bool>(false, false);
            //try
            //{
                HOperatorSet.GenEmptyObj(out m_imageAuto);
                m_imageAuto.Dispose();
                Camera.GrabOnePic(out m_imageAuto);
                try
                {
                    HOperatorSet.DispObj(m_imageAuto, hv_win);
                }
                catch 
                {
                }
                detection_result = Tray_Detection(m_imageAuto, row, col, phi, lenth1, lenth2, threshold, minarea);
                if (true)
                {

                }
            //}
            //catch
            //{

            //}

            return detection_result;
        }

        private void SaveImage(string type, HObject m_image)   //保存照片
        {
            HOperatorSet.WriteImage(m_image, "tiff", 0, Application.StartupPath + "\\SaveImage\\" + type + "-" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss.fff") + ".tiff");

        }
        private string Tray_Detection(HObject image, double row, double col, double phi, double lenth1, double lenth2, double threshold, double min_area)
        {
            //Tuple<bool, bool> str = new Tuple<bool, bool>(false, false);
            string str = "";
            //try
            //{
                bool b_model = Find_Model_(image);
                //b_model = false;
                // Local iconic variables 

                HObject ho_Rectangle = null, ho_ImageReduced = null;
                HObject ho_Regions = null, ho_RegionOpening = null, ho_ConnectedRegions = null;
                HObject ho_SelectedRegions = null;

                // Local control variables 

                HTuple hv_Number = new HTuple();
                // Initialize local and output iconic variables 
                HOperatorSet.GenEmptyObj(out ho_Rectangle);
                HOperatorSet.GenEmptyObj(out ho_ImageReduced);
                HOperatorSet.GenEmptyObj(out ho_Regions);
                HOperatorSet.GenEmptyObj(out ho_RegionOpening);
                HOperatorSet.GenEmptyObj(out ho_ConnectedRegions);
                HOperatorSet.GenEmptyObj(out ho_SelectedRegions);

                ho_Rectangle.Dispose();
                HOperatorSet.GenRectangle2(out ho_Rectangle, row, col, phi, lenth1, lenth2);
                HOperatorSet.SetColor(hv_win, "red");
                HOperatorSet.SetDraw(hv_win, "margin");
                HOperatorSet.DispObj(ho_Rectangle, hv_win);
                ho_ImageReduced.Dispose();
                HOperatorSet.ReduceDomain(image, ho_Rectangle, out ho_ImageReduced);
                ho_Regions.Dispose();
                HOperatorSet.Threshold(ho_ImageReduced, out ho_Regions, threshold, 255);
                ho_RegionOpening.Dispose();
                HOperatorSet.OpeningCircle(ho_Regions, out ho_RegionOpening, 3.5);
                ho_ConnectedRegions.Dispose();
                HOperatorSet.Connection(ho_RegionOpening, out ho_ConnectedRegions);
                ho_SelectedRegions.Dispose();
                HOperatorSet.SelectShape(ho_ConnectedRegions, out ho_SelectedRegions, "area", "and", min_area, 99999999);
                HOperatorSet.CountObj(ho_SelectedRegions, out hv_Number);
                if (hv_Number > 0)
                {
                    HOperatorSet.SetDraw(hv_win, "fill");
                    HOperatorSet.DispObj(ho_SelectedRegions, hv_win);
                }
                ho_Rectangle.Dispose();
                ho_ImageReduced.Dispose();
                ho_Regions.Dispose();
                ho_RegionOpening.Dispose();
                ho_ConnectedRegions.Dispose();
                ho_SelectedRegions.Dispose();
                if (hv_Number != 0 )
                {
                    SaveImage("异物", image);
                    str = "异物";
                }
                else if (b_model)
                {
                    SaveImage("膜", image);
                    str = "膜";
                }
                else
                {
                    str = "OK";
                }
                
            //}
            //catch
            //{
            //    SaveImage("Catch", image);
            //    //str = new Tuple<bool, bool>(false, false);
            //    str = "NG";
            //}

            return str;
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            Thread.Sleep(10);
            HTuple hv_row = null, hv_col = null, hv_phi = null, hv_lenth1 = null, hv_lenth2 = null;
            try
            {
                HOperatorSet.DrawRectangle2(hv_win, out hv_row, out hv_col, out hv_phi, out hv_lenth1, out hv_lenth2);
                OperateIniFile.WriteIniData("Device", CameraName +"row", hv_row.ToString(), Application.StartupPath + @"\Tool\Device.ini");
                OperateIniFile.WriteIniData("Device", CameraName + "col", hv_col.ToString(), Application.StartupPath + @"\Tool\Device.ini");
                OperateIniFile.WriteIniData("Device", CameraName + "phi", hv_phi.ToString(), Application.StartupPath + @"\Tool\Device.ini");
                OperateIniFile.WriteIniData("Device", CameraName + "lenth1", hv_lenth1.ToString(), Application.StartupPath + @"\Tool\Device.ini");
                OperateIniFile.WriteIniData("Device", CameraName + "lenth2", hv_lenth2.ToString(), Application.StartupPath + @"\Tool\Device.ini");
                row = Convert.ToDouble(OperateIniFile.ReadIniData("Device", CameraName + "row", "", Application.StartupPath + @"\Tool\Device.ini"));
                col = Convert.ToDouble(OperateIniFile.ReadIniData("Device", CameraName + "col", "", Application.StartupPath + @"\Tool\Device.ini"));
                phi = Convert.ToDouble(OperateIniFile.ReadIniData("Device", CameraName + "phi", "", Application.StartupPath + @"\Tool\Device.ini"));
                lenth1 = Convert.ToDouble(OperateIniFile.ReadIniData("Device", CameraName + "lenth1", "", Application.StartupPath + @"\Tool\Device.ini"));
                lenth2 = Convert.ToDouble(OperateIniFile.ReadIniData("Device", CameraName + "lenth2", "", Application.StartupPath + @"\Tool\Device.ini"));
                Log4Net.MsgInfo("修改区域成功");
            }
            catch
            {
                Log4Net.MsgInfo("修改区域失败");
            }
        }




        private bool Find_Model_(HObject image)
        {
            string Model = "";
            if (CameraName == "CameraA")
            {
                Model = "modelA.shm";
                return Find_ModelA(Model, image);
            }
            else
            {
                Model = "modelB.shm";
                return Find_ModelB(Model, image);
            }
            return Find_Model(Model, image);


        }
        private static bool Find_ModelA(string model, HObject image)
        {
            try
            {
                // Local iconic variables 

                // Local control variables 

                HTuple hv_ModelID = null, hv_Row = null, hv_Column = null;
                HTuple hv_Angle = null, hv_Scale = null, hv_Score = null;
                // Initialize local and output iconic variables 
                HOperatorSet.ReadShapeModel("modelA.shm", out hv_ModelID);
                HOperatorSet.FindScaledShapeModel(image, hv_ModelID, -0.39,
                    0.78, 0.9, 1.1, 0.75, 1, 0.5, "least_squares", 0, 0.9, out hv_Row, out hv_Column,
                    out hv_Angle, out hv_Scale, out hv_Score);
                HOperatorSet.ClearShapeModel(hv_ModelID);
            if (hv_Score.Length > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
        }
            catch
            {
                Log4Net.MsgInfo("模板匹配异常");
                return true;
            }


}

        private static bool Find_ModelB(string model, HObject image)
        {
            try
            {
                // Local iconic variables 

                // Local control variables 

                HTuple hv_ModelID = null, hv_Row = null, hv_Column = null;
            HTuple hv_Angle = null, hv_Scale = null, hv_Score = null;
            // Initialize local and output iconic variables 
            HOperatorSet.ReadShapeModel("modelB.shm", out hv_ModelID);
            HOperatorSet.FindScaledShapeModel(image, hv_ModelID, -0.39,
                0.78, 0.9, 1.1, 0.75, 1, 0.5, "least_squares", 0, 0.9, out hv_Row, out hv_Column,
                out hv_Angle, out hv_Scale, out hv_Score);
            HOperatorSet.ClearShapeModel(hv_ModelID);
            if (hv_Score.Length > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
            }
            catch
            {
                Log4Net.MsgInfo("模板匹配异常");
                return true;
            }


        }

        private static bool Find_Model(string model, HObject image)
        {
            //try
            //{
            // Local iconic variables 

            // Local control variables 

            HTuple hv_ModelID = null, hv_Row = null, hv_Column = null;
            HTuple hv_Angle = null, hv_Scale = null, hv_Score = null;
            // Initialize local and output iconic variables 
            HOperatorSet.ReadShapeModel(model, out hv_ModelID);
            HOperatorSet.FindScaledShapeModel(image, hv_ModelID, -0.39,
                0.78, 0.9, 1.1, 0.75, 1, 0.5, "least_squares", 0, 0.9, out hv_Row, out hv_Column,
                out hv_Angle, out hv_Scale, out hv_Score);
            HOperatorSet.ClearShapeModel(hv_ModelID);
            if (hv_Score.Length > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
            //}
            //catch
            //{
            //    Log4Net.MsgInfo("模板匹配异常");
            //    return true;
            //}


        }
    }
}
